package com.fun_ordering.service.impl;

import com.fun_ordering.components.ApiResponse;
import com.fun_ordering.entity.LoginUser;
import com.fun_ordering.mapper.FoEmployeeMapper;
import com.fun_ordering.pojo.FoEmployee;
import com.fun_ordering.pojo.FoEmployeeExample;
import com.fun_ordering.service.LoginService;
import com.fun_ordering.util.JJwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author 陈星
 * @date 2024/3/24 15:04
 */
@Service
public class LoginServiceImpl implements LoginService {

    /**
     * 认证管理器
     */
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private FoEmployeeMapper foEmployeeMapper;
    @Autowired
    private PasswordEncoder passwordEncoder;


    @Override
    public FoEmployee login2(String username, String password) {

        //集合中只能为当前用户信息
        FoEmployee foEmployee1 = foEmployeeMapper.selectByOne(username);
        List<FoEmployee> foEmployees = (List<FoEmployee>) foEmployee1;
        if (!ObjectUtils.isEmpty(foEmployee1)){
            //密码校验
            if (foEmployee1.getEmpPassword().equals(password)){
                //将查到的密码设置为null,目的是脱敏
                foEmployee1.setEmpPassword(null);
                return foEmployee1;
            }
        }
        return null;
    }

    @Override
    public ApiResponse login(FoEmployee foEmployee) {
        //获取当前登陆人的名字 =>鉴权  如果没有登录返回anonymous
        SecurityContextHolder.getContext().getAuthentication().getName();

        //通过UsernamePasswordAuthenticationToken获取用户名和密码
        UsernamePasswordAuthenticationToken authenticationToken=new UsernamePasswordAuthenticationToken(foEmployee.getEmpAccount(),foEmployee.getEmpPassword());

        //AuthenticationManager委托机制对authenticationToken 进行用户认证  底层调用UserDetailsServiceImpl的loadUserByUsername
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);

        //如果认证没有通过，给出对应的提示
        if (Objects.isNull(authenticate)){
            throw new RuntimeException("登录失败");
        }
        //如果认证通过，使用user生成jwt  jwt存入ResponseResult 返回
        //如果认证通过，拿到这个当前登录用户信息
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
        //脱敏
        loginUser.getFoEmployee().setEmpPassword(null);
//        通过redis存入token解析token
        String token = JJwtUtil.getJwtToken(loginUser.getFoEmployee());
        //把完整的用户信息存入redis  userid为key   用户信息为value
        stringRedisTemplate.opsForValue().set("login:user:"+foEmployee.getEmpAccount(),token);
        //失效策略
        stringRedisTemplate.expire("login:user:"+foEmployee.getEmpAccount(),2, TimeUnit.HOURS);
        //返回一个token
        return ApiResponse.success(token);
    }

    @Override
    public void register(FoEmployee foEmployee) {
        foEmployeeMapper.insert(foEmployee);
    }

    @Override
    public void logout(String username) {
        //把完整的用户信息存入redis  userid为key   用户信息为value
        //把用户信息 删除,即退出功能
        stringRedisTemplate.delete("login:user:"+username);
    }
}
